package com.zxy.ziems.server.collection.task;

import com.zxy.btp.common.response.PageResult;
import com.zxy.ziems.server.collection.mapper.DLMapper;
import com.zxy.ziems.server.collection.pojo.entity.CollectionDevicePropertyParam;
import com.zxy.ziems.server.collection.pojo.entity.DlAccPoint;
import com.zxy.ziems.server.collection.pojo.entity.DlPointEntity;
import com.zxy.ziems.server.collection.service.CollectionService;
import com.zxy.ziems.server.collection.service.DlPointService;
import com.zxy.ziems.server.device.service.DevicePropertyService;
import com.zxy.ziems.server.mybatis.core.pojo.PageParam;
import com.zxy.ziems.server.sync.enums.SyncMetaType;
import com.zxy.ziems.server.sync.service.SyncMetaService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * 采集器任务
 */
@Component
@Slf4j
public class CollectionTask {

    @Autowired
    private CollectionService collectionService;
    @Autowired
    private DevicePropertyService devicePropertyService;
    @Autowired
    private DlPointService dlPointService;
    @Autowired
    private DLMapper dlMapper;
    @Autowired
    private SyncMetaService syncMetaService;


    /**
     * 同步FMCS水数据
     */
    @Scheduled(cron = "0 35 0 * * ?")
    public void sync() {
        syncFmcsWater();
    }

    private void syncFmcsWater() {
        log.info("============FMCS采集任务开始===============");

        Integer pageNo = 1;
        Integer pageSize = 2000;
        // 获取设备属性
        while (true) {
            log.info("获取FMCS页码：no={}, size={}", pageNo, pageSize);
            PageParam page = new PageParam(pageNo++, pageSize);
            PageResult<CollectionDevicePropertyParam> pageResult = devicePropertyService.selectDeviceProperty(page);
            log.info("开始同步FMCS水数据[syncFmcsWater]");
            // 同步数据
            List<CollectionDevicePropertyParam> list = pageResult.getList();
            if (CollectionUtils.isEmpty(list)) break;
            collectionService.syncDevicePropertyValue(list);
        }

        log.info("============FMCS采集任务结束===============");
    }

    /**
     * 同步FMCS电力数据
     */
    @Scheduled(cron = "0 2,33 * * * ?")
    public void syncFmcsDl() {
        syncFmcsDlData();
    }


    /**
     * 同步FMCS电力数据
     */
    public void syncFmcsDlData() {
        Integer pageSize;
        Integer pageNo;
        log.info("============FMCS采集任务(电量)开始===============");

        pageNo = 1;
        pageSize = 2000;
        // 获取设备属性
        while (true) {
            log.info("获取FMCS页码：no={}, size={}", pageNo, pageSize);
            PageParam page = new PageParam(pageNo++, pageSize);
            PageResult<CollectionDevicePropertyParam> pageResult = devicePropertyService.selectFmcsDl(page);
            // 同步数据
            log.info("开始同步FMCS电力数据[syncFmcsDlData]");
            List<CollectionDevicePropertyParam> list = pageResult.getList();
            if (CollectionUtils.isEmpty(list)) break;
            log.info("设备数量:" + list.size());
            collectionService.syncDevicePropertyValue(list);
        }

        log.info("============FMCS采集任务(电量)结束===============");
    }

    /**
     * 同步电力点位信息，每日一次
     */
    @Scheduled(cron = "0 0 1 * * ?")
    public void syncDlPoint() {
        log.info("============DL点位同步开始===============");

        // 获取点位信息
        List<DlAccPoint> dlAccPoints = dlMapper.pointList();
        log.info("同步电力点位信息[syncDlPoint]");
        List<DlPointEntity> list = new ArrayList<>();
        dlAccPoints.forEach(m -> {
            DlPointEntity e = new DlPointEntity();
            BeanUtils.copyProperties(m, e);
            e.setPointDesc(m.getPointDesc().replace("_正向有功电度", "").replace("_正向有功电能", "").trim());
            list.add(e);
        });
        log.info("电力点位信息数量:" + list.size());
        dlPointService.batchAdd(list);


        log.info("============DL点位同步完成===============");
    }

    /**
     * 同步电力点位数据
     */
    @Scheduled(cron = "0 3,34 * * * ?")
    public void syncDlVal() {
        log.info("============DL数据同步开始===============");

        Integer pageNo = 1;
        Integer pageSize = 2000;
        // 获取设备属性
        while (true) {
            log.info("获取DL页码：no={}, size={}", pageNo, pageSize);
            PageParam page = new PageParam(pageNo++, pageSize);
            PageResult<CollectionDevicePropertyParam> pageResult = devicePropertyService.selectDlDeviceProperty(page);
            log.info("同步电力点位数据[syncDlVal]");
            // 同步数据
            List<CollectionDevicePropertyParam> list = pageResult.getList();
            if (CollectionUtils.isEmpty(list)) break;
            log.info("电力点位数据数量:" + list.size());
            collectionService.syncDlDevicePropertyValue(list);
        }


        log.info("============DL数据同步结束===============");
    }


    /**
     * 水科total实际值任务
     */
    @Scheduled(cron = "0 0,30 * * * ?")
    public void syncWaterTotal() {
        log.info("============水科Total实际值采集任务开始===============");

        Integer pageNo = 1;
        Integer pageSize = 2000;
        while (true) {
            log.info("获取设备水科需要采集设备页码：no={}, size={}", pageNo, pageSize);
            PageParam page = new PageParam(pageNo++, pageSize);
            PageResult<CollectionDevicePropertyParam> pageResult = devicePropertyService.selectDeviceWaterTotalRealProperty(page);
            // 同步数据
            List<CollectionDevicePropertyParam> list = pageResult.getList();
            if (CollectionUtils.isEmpty(list)) break;
            collectionService.syncWaterTotalDevicePropertyValue(list);
        }


        log.info("============水科Total实际值任务结束===============");
    }

    /**
     * FMCS实际值任务
     */
    @Scheduled(cron = "0 1,32 * * * ?")
    public void syncReal() {
        log.info("============FMCS实际值采集任务开始===============");

        Integer pageNo = 1;
        Integer pageSize = 2000;
        while (true) {
            log.info("获取FMCS页码：no={}, size={}", pageNo, pageSize);
            PageParam page = new PageParam(pageNo++, pageSize);
            PageResult<CollectionDevicePropertyParam> pageResult = devicePropertyService.selectDeviceFmcsRealProperty(page);
            // 同步数据
            List<CollectionDevicePropertyParam> list = pageResult.getList();
            if (CollectionUtils.isEmpty(list)) break;
            collectionService.syncDevicePropertyValue(list);
        }


        log.info("============FMCS采集任务结束===============");
    }

    /**
     * FMCS PV(大宗气体)值采集
     */
    @Scheduled(cron = "0 1,32 * * * ?")
    public void syncFmcsPv() {
        log.info("============FMCS PV值采集任务开始===============");

        Integer pageNo = 1;
        Integer pageSize = 2000;
        while (true) {
            log.info("获取FMCS页码：no={}, size={}", pageNo, pageSize);
            PageParam page = new PageParam(pageNo++, pageSize);
            PageResult<CollectionDevicePropertyParam> pageResult = devicePropertyService.selectDeviceFmcsPvProperty(page);
            // 同步数据
            List<CollectionDevicePropertyParam> list = pageResult.getList();
            if (CollectionUtils.isEmpty(list)) break;
            collectionService.syncDevicePropertyValue(list);
        }


        log.info("============FMCS PV值采集任务结束===============");
    }


    /**
     * FMCS通用采集器，可根据后缀配置区分
     */
    @Scheduled(cron = "0 0,30 * * * ?")
    public void syncFmcs() {
        log.info("============FMCS collection 采集任务开始===============");

        Integer pageNo = 1;
        Integer pageSize = 2000;
        while (true) {
            log.info("获取FMCS页码：no={}, size={}", pageNo, pageSize);
            PageParam page = new PageParam(pageNo++, pageSize);
            PageResult<CollectionDevicePropertyParam> pageResult = devicePropertyService.selectDeviceFmcsProperty(page);
            // 同步数据
            List<CollectionDevicePropertyParam> list = pageResult.getList();
            if (CollectionUtils.isEmpty(list)) break;
            collectionService.syncDevicePropertyValue(list);
        }

        log.info("============FMCS collection 采集任务结束===============");
    }


    /**
     * 水科纯废水系统电力数据采集
     * 用电量、用水量
     * 每30分钟一次
     */
//    @Scheduled(cron = "0 0,30 * * * ?")
    public void syncWaterDlData() {
        // TODO: 还没改好
        Integer pageSize;
        Integer pageNo;
        log.info("============水科纯废水电力数据采集任务开始===============");

        pageNo = 1;
        pageSize = 2000;
        // 获取设备属性
        while (true) {
            log.info("获取FMCS页码：no={}, size={}", pageNo, pageSize);
            PageParam page = new PageParam(pageNo++, pageSize);
            // 通过不同的标识状态去查询相应的设备，再从相应的数据库中查询数据
            PageResult<CollectionDevicePropertyParam> pageResult = devicePropertyService.selectDeviceWaterDlProperty(page);
            // 同步数据
            log.info("开始同步水科纯废水电力数据[syncWaterDlData]");
            List<CollectionDevicePropertyParam> list = pageResult.getList();
            if (CollectionUtils.isEmpty(list)) break;
            log.info("设备数量:" + list.size());
            collectionService.syncWaterDlDevicePropertyValue(list);
        }

        log.info("============水科纯废水电力数据采集任务结束===============");
    }

    /**
     * 水科纯废水系统化学品数据采集
     * 用电量、用水量
     * 每30分钟一次
     */
//    @Scheduled(cron = "0 0,30 * * * ?")
    public void syncWaterChemicalData() {
        // TODO: 还没改好
        Integer pageSize;
        Integer pageNo;
        log.info("============水科纯废水化学品采集任务开始===============");

        pageNo = 1;
        pageSize = 2000;
        // 获取设备属性
        while (true) {
            log.info("获取FMCS页码：no={}, size={}", pageNo, pageSize);
            PageParam page = new PageParam(pageNo++, pageSize);
            // 通过不同的标识状态去查询相应的设备，再从相应的数据库中查询数据
            PageResult<CollectionDevicePropertyParam> pageResult = devicePropertyService.selectDeviceWaterChemicalProperty(page);
            // 同步数据
            log.info("开始同步水科纯废水化学品数据[syncWaterChemicalData]");
            List<CollectionDevicePropertyParam> list = pageResult.getList();
            if (CollectionUtils.isEmpty(list)) break;
            log.info("设备数量:" + list.size());
            collectionService.syncWaterChemicalDevicePropertyValue(list);
        }

        log.info("============水科纯废水化学品采集任务结束===============");
    }

    /**
     * CIM系统电力数据采集
     * 各个工艺段的电数据
     * 每30分钟一次
     */
//    @Scheduled(cron = "0 0,30 * * * ?")
    public void syncCimDlData() {
        // TODO: 还没改好
        Integer pageSize;
        Integer pageNo;
        log.info("============CIM电力数据采集任务开始===============");

        pageNo = 1;
        pageSize = 2000;
        // 获取设备属性
        while (true) {
            log.info("获取FMCS页码：no={}, size={}", pageNo, pageSize);
            PageParam page = new PageParam(pageNo++, pageSize);
            // 通过不同的标识状态去查询相应的设备
            PageResult<CollectionDevicePropertyParam> pageResult = devicePropertyService.selectDeviceCIMDlProperty(page);
            // 同步数据
            log.info("开始同步CIM电力数据[syncCimDlData]");
            List<CollectionDevicePropertyParam> list = pageResult.getList();
            if (CollectionUtils.isEmpty(list)) break;
            log.info("设备数量:" + list.size());
            // 根据设备获取对应数据
            collectionService.syncCIMDlDevicePropertyValue(list);
        }

        log.info("============CIM电力数据采集任务开始===============");
    }

    /**
     * CIM系统水数据采集
     * 各个工艺段的水数据
     * 每30分钟一次
     */
//    @Scheduled(cron = "0 0,30 * * * ?")
    public void syncCimWaterData() {
        // TODO: 还没改好
        Integer pageSize;
        Integer pageNo;
        log.info("============CIM水数据采集任务开始===============");

        pageNo = 1;
        pageSize = 2000;
        // 获取设备属性
        while (true) {
            log.info("获取FMCS页码：no={}, size={}", pageNo, pageSize);
            PageParam page = new PageParam(pageNo++, pageSize);
            // 通过不同的标识状态去查询相应的设备
            PageResult<CollectionDevicePropertyParam> pageResult = devicePropertyService.selectDeviceCIMWaterProperty(page);
            // 同步数据
            log.info("开始同步CIM水数据[syncCimWaterData]");
            List<CollectionDevicePropertyParam> list = pageResult.getList();
            if (CollectionUtils.isEmpty(list)) break;
            log.info("设备数量:" + list.size());
            // 根据设备获取对应数据
            collectionService.syncCIMWaterDevicePropertyValue(list);
        }

        log.info("============CIM水数据采集任务结束===============");
    }

    /**
     * CIM系统气数据采集
     * 各个工艺段的气数据
     * 每30分钟一次
     */
//    @Scheduled(cron = "0 0,30 * * * ?")
    public void syncCimGasData() {
        // TODO: 还没改好
        Integer pageSize;
        Integer pageNo;
        log.info("============CIM水数据采集任务开始===============");

        pageNo = 1;
        pageSize = 2000;
        // 获取设备属性
        while (true) {
            log.info("获取FMCS页码：no={}, size={}", pageNo, pageSize);
            PageParam page = new PageParam(pageNo++, pageSize);
            // 通过不同的标识状态去查询相应的设备
            PageResult<CollectionDevicePropertyParam> pageResult = devicePropertyService.selectDeviceCIMGasProperty(page);
            // 同步数据
            log.info("开始同步CIM气数据[syncCimWaterData]");
            List<CollectionDevicePropertyParam> list = pageResult.getList();
            if (CollectionUtils.isEmpty(list)) break;
            log.info("设备数量:" + list.size());
            // 根据设备获取对应数据
            collectionService.syncCIMGasDevicePropertyValue(list);
        }

        log.info("============CIM气数据采集任务结束===============");
    }


    /**
     * 手工填报天然气数据采集
     * 可以不用每天同步，没有开启定时任务，
     * 因为化学品每次新增、编辑、删除、批量导入时会同步数据，不用定时同步
     */
//    @Scheduled(cron = "0 0 1 * * ?")
    public void syncManualInputNaturalGasData() {
        Integer pageSize;
        Integer pageNo;
        log.info("============手工填报天然气数据采集任务开始===============");

        pageNo = 1;
        pageSize = 2000;
        // 获取设备属性
        while (true) {
            log.info("获取FMCS页码：no={}, size={}", pageNo, pageSize);
            PageParam page = new PageParam(pageNo++, pageSize);
            // 通过不同的标识状态去查询相应的设备
            PageResult<CollectionDevicePropertyParam> pageResult = devicePropertyService.selectManualInputNaturalGasProperty(page);
            // 同步数据
            log.info("开始同步手工填报天然气数据[syncManualInputNaturalGasData]");
            List<CollectionDevicePropertyParam> list = pageResult.getList();
            if (CollectionUtils.isEmpty(list)) break;
            log.info("设备数量:" + list.size());
            // 根据设备获取对应数据
            collectionService.syncManualInputNaturalGasPropertyValue(list);
        }

        log.info("============手工填报天然气数据采集任务结束===============");
    }

    /**
     * 手工填报化学品数据采集
     * 不用进行定时任务同步，每次人员填报时同步，新增、删除和批量导入
     */
//    @Scheduled(cron = "0 0 1 * * ?")
    public void syncManualInputChemicalsData() {
        // TODO: 不能用，程序不完善，因为化学品每次新增、编辑、删除、批量导入时会同步数据，不用定时同步
        Integer pageSize;
        Integer pageNo;
        log.info("============手工填报化学品数据采集任务开始===============");

        pageNo = 1;
        pageSize = 2000;
        // 获取设备属性
        while (true) {
            log.info("获取FMCS页码：no={}, size={}", pageNo, pageSize);
            PageParam page = new PageParam(pageNo++, pageSize);
            // 通过不同的标识状态去查询相应的设备
            PageResult<CollectionDevicePropertyParam> pageResult = devicePropertyService.selectManualInputChemicalsProperty(page);
            // 同步数据
            log.info("开始同步手工填报化学品数据[syncManualInputChemicalsData]");
            List<CollectionDevicePropertyParam> list = pageResult.getList();
            if (CollectionUtils.isEmpty(list)) break;
            log.info("设备数量:" + list.size());
            // 根据设备获取对应数据
            collectionService.selectManualInputChemicalsPropertyValue(list);
        }

        log.info("============手工填报化学品数据采集任务结束===============");
    }


    /**
     * 水科 (自来水,CDA,N2,H2)数据采集
     * 每天执行一次
     */
    @Scheduled(cron = "0 15 0 * * ?")
//        @Scheduled(cron = "0 */1 * * * ?")
    public void syncWaterData() {
        Integer pageSize;
        Integer pageNo;
        log.info("============水科 (自来水,CDA,N2,H2)数据采集任务开始===============");

        pageNo = 1;
        pageSize = 2000;
        // 获取设备属性
        while (true) {
            log.info("获取FMCS页码：no={}, size={}", pageNo, pageSize);
            PageParam page = new PageParam(pageNo++, pageSize);
            // 通过不同的标识状态去查询相应的设备，再从相应的数据库中查询数据
            PageResult<CollectionDevicePropertyParam> pageResult = devicePropertyService.selectDeviceWaterProperty(page);
            // 同步数据
            log.info("开始同步水科(自来水,CDA,N2,H2)数据[syncWaterData]");
            List<CollectionDevicePropertyParam> list = pageResult.getList();
            if (CollectionUtils.isEmpty(list)) break;
            log.info("设备数量:" + list.size());
            collectionService.syncWaterDevicePropertyValue(list);
        }

        log.info("============水科 (自来水,CDA,N2,H2)数据采集任务结束===============");
    }


    /**
     * ems 同步cim数据
     * 每天执行一次
     */
    @Scheduled(cron = "0 5,35 * * * ?")
    public void syncDayDataToCim() {
        log.info("============ems 同步cim数据 采集任务开始===============");

        LocalDateTime syncTime = syncMetaService.getSyncTime(SyncMetaType.SYNC_EMS_CIM_DAY_DATA.getCode());
        LocalDate date = syncTime.toLocalDate().plusDays(1);
        LocalDate yesterday = LocalDate.now().plusDays(-1);
        while (true) {
            if (!(date.compareTo(yesterday) < 1)) {
                break;
            }

            //  同步
            collectionService.syncDayDataToCim(date);
            syncMetaService.saveSyncTime(date.atStartOfDay(), SyncMetaType.SYNC_EMS_CIM_DAY_DATA.getCode());
            date = date.plusDays(1);
        }


        log.info("============ems 同步cim数据 采集任务结束===============");
    }

}
